﻿using ThresholdAssistant.Tools;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace ThresholdAssistant.Http.Extensions
{
    /// <summary>
    /// HttpClientFactory业务扩展处理类
    /// </summary>
    public static class HttpClientFactoryExtensions
    {
        /// <summary>
        /// Get接口请求
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="factory">工厂类</param>
        /// <param name="url"></param>
        /// <param name="paramters"></param>
        /// <param name="headers"></param>
        /// <param name="timeoutSeconds">超时时间</param>
        /// <returns></returns>
        public static async Task<T> GetAsync<T>(this IHttpClientFactory factory, string url, Dictionary<string, string> paramters = null, Dictionary<string, string> headers = null, int timeoutSeconds = 3)
        {
            T result = default;
            try
            {
                if (string.IsNullOrEmpty(url))
                {
                    return result;
                }

                var requestUri = url.ToGetUrl(paramters);
                using var client = factory.CreateClient();
                client.DefaultRequestHeaders.AddHeaders(headers);
                client.Timeout = TimeSpan.FromSeconds(timeoutSeconds);
                using var response = await client.GetAsync(requestUri);
                if (!response.IsSuccessStatusCode)
                {
                    //请求状态不对的时候抛出异常信息
                    throw new HttpRequestException($"StatusCode：{(int)response.StatusCode}，ReasonPhrase：{response.ReasonPhrase}");
                }
                var responseJsonValue = await response.Content.ReadAsStringAsync();
                result = responseJsonValue.DeserializeObject<T>();//反序列化请求参数
                headers = null;
                paramters = default;
                responseJsonValue = null;
            }
            catch (TaskCanceledException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        /// <summary>
        /// 发送Post请求
        /// </summary>
        /// <typeparam name="R">请求模型</typeparam>
        /// <typeparam name="T">返回模型</typeparam>
        /// <param name="factory">工厂类</param>
        /// <param name="url"></param>
        /// <param name="paramters"></param>
        /// <param name="headers"></param>
        /// <param name="contentType">协议类型</param>
        /// <param name="timeoutSeconds">超时时间</param>
        /// <returns></returns>
        public static async Task<T> PostAsync<R, T>(this IHttpClientFactory factory, string url, R paramters, Dictionary<string, string> headers = null, string contentType = "application/json", int timeoutSeconds = 3)
        {
            T result = default;
            try
            {
                if (string.IsNullOrEmpty(url))
                    return result;

                HttpContent httpContent = new StringContent(paramters.SerializeObject(), Encoding.UTF8);
                httpContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);

                using var client = factory.CreateClient();
                client.DefaultRequestHeaders.AddHeaders(headers);
                client.Timeout = TimeSpan.FromSeconds(timeoutSeconds);
                using var response = await client.PostAsync(url, httpContent);
                if (!response.IsSuccessStatusCode)
                {
                    //请求状态不对的时候抛出异常信息
                    throw new HttpRequestException($"StatusCode：{(int)response.StatusCode}，ReasonPhrase：{response.ReasonPhrase}");
                }

                var responseJsonValue = await response.Content.ReadAsStringAsync();
                result = responseJsonValue.DeserializeObject<T>();//反序列化请求参数
                headers = null;
                paramters = default;
                responseJsonValue = null;
            }
            catch (TaskCanceledException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }
    }
}